﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Mogre;
using MogreNewt;

namespace WastedMechanics
{
    public class Described : SelectableObject
    {
        public DescribedProfile Profile;

        Entity Entity;
        SceneNode Node;
        Body Body;

        public Item Item;

        public Described(DescribedProfile profile)
            : this(profile, Vector3.UNIT_Z.GetRotationTo(
                new Vector3(
                    Mogre.Math.UnitRandom() - 0.5f,
                    Mogre.Math.UnitRandom() - 0.5f,
                    Mogre.Math.UnitRandom() - 0.5f
                    )))

        { 
        }

        public Described(DescribedProfile profile, Quaternion orientation)
        {
            Profile = profile.Clone();
            ShowName = true;
            IsObstacle = true;
            
            Entity = Engine.SceneManager.CreateEntity(Profile.MeshName);
            Node = Engine.SceneManager.RootSceneNode.CreateChildSceneNode();
            Node.AttachObject(Entity);
            Entity.CastShadows = true;
        
            Vector3 scaledSize = Entity.BoundingBox.Size * Profile.BodyScaleFactor;

            ConvexCollision collision = new MogreNewt.CollisionPrimitives.Box(
                Engine.NewtonWorld,                                
                scaledSize,
                Quaternion.IDENTITY,
                Engine.GetUniqueBodyId());


            Vector3 inertia, offset;
            collision.CalculateInertialMatrix(out inertia, out offset);
            
            Body = new Body(Engine.NewtonWorld, collision, true);
            Body.AttachNode(Node);
            Body.SetMassMatrix(Profile.Mass, Profile.Mass * inertia);

            Body.UserData = this;
            Body.MaterialGroupID = Engine.MaterialManager.Materials["Described"];
            Body.ContinuousCollisionMode = 1;            

            collision.Dispose();

            Orientation = orientation;
        }

        public Described(Item item) : this(item.Profile)
        {
            Item = item;
        }

        public void GetHit(ProjectileBullet proj, Vector3 where)
        {
            Body.AddImpulse(proj.Direction * 3, where);
        }

        public override Vector3 Position
        {
            get
            {
                return Body.Position;
            }
            set
            {
                Body.SetPositionOrientation(value, Orientation);
            }
        }

        public override void Update()
        {                                    
        }

        public override Quaternion Orientation
        {
            get
            {
                return Body.Orientation;
            }
            set
            {
                Body.SetPositionOrientation(Body.Position, value);
            }
        }

        public override string DisplayName
        {
            get
            {
                return Profile.DisplayName;
            }
            set
            {
                Profile.DisplayName = value;
            }
        }

        public override string Description
        {
            get
            {
                return Profile.Description;
            }
            set
            {
                Profile.Description = value;
            }
        }

        public override Vector3 DisplayNameOffset
        {
            get
            {
                return Profile.DisplayNameOffset;
            }
            set
            {
                Profile.DisplayNameOffset = value;
            }
        }

        public bool IsPickable
        {
            get { return Profile.IsPickable; }
        }

        public override void Destroy()
        {
            Node.DetachAllObjects();
            Engine.SceneManager.DestroySceneNode(Node);
            Engine.SceneManager.DestroyEntity(Entity);
            Body.Dispose();
            Body = null;

            base.Destroy();
        }
    }
}
